home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 62.8 KB | 2,256 lines | [TEXT/MPS ] |
- /*
- File: FontDBaseDocument.c
-
- Contains: QuickDraw GX to PostScript conversion code.
- File contains code to union page font databases into a document database.
-
- Version: Technology: Quickdraw GX 1.1.x
-
- Copyright: © 1991-1997 by Apple Computer, Inc., all rights reserved.
- */
-
- // allow multiple references to single label
- #define resumeLabel(exception)
-
- #include <Resources.h>
- #include "GXExceptions.h"
- #include "GXPrintingUniverse.h"
- #include "IOUtilities.h"
-
- #include "FontDataBase.h"
- #include "FontDBasePrivate.h"
- #include "ImageCompression.h"
- #include "QuickDraw.h"
-
- #include "string.h"
-
- #if DEBUGLEVEL > 0
- #define ASSERT(trueCondition, message) if (!(trueCondition)) dprintf(notrace, message); else
-
- static void AssertNoSfntReferences(Handle fond)
- {
- const short* FAT = (const short*)((const FamRec*)*fond + 1);
- int FATCountBase0 = *FAT++;
-
- if (FAT[pointSizeIndex] == 0)
- dprintf(notrace, "NFNT gxFont matched a FOND %08lx with a FAT entry for an sfnt", fond);
- }
- #else
- #define ASSERT(trueCondition, message)
- #define AssertNoSfntReferences(fond)
- #endif
-
- /************************
-
- CopyResourceToHandle makes a copy of a loaded resource and returns the new Handle
- in the same parameter. This is called instead of DetachResource 'cause the FM
- doesn't like it when you detach a font that's being used (like Geneva 9 italic)
-
- ************************/
- static OSErr CopyResourceToHandle(Handle* h)
- {
- OSErr status;
- int state;
- long size;
- Handle newh;
-
- state = HGetState(*h);
- HNoPurge(*h);
- size = GetResourceSizeOnDisk(*h);
- status = PrNewHandle(&newh, size);
- HSetState(*h, state);
- nrequire(status, failed_new_handle);
- BlockMoveData(**h, *newh, size);
- *h = newh;
-
- failed_new_handle:
- return status;
- }
-
- #if !GXTOPOSTSCRIPTLIBRARY
-
- /************************
-
- FDBDeleteFATEntry:
-
- Delete the FAT entry from the FOND, and update any offsets to reflect the new, smaller FOND.
-
- *************************/
- static void FDBDeleteFATEntry(Handle fond, short FAT[])
- {
- FamRec* fam = (FamRec*)*fond;
- short* nextFAT = FAT + shortsInAFATRecord;
-
- (*(short*)(fam + 1))--; /* reduce the FAT count */
-
- BlockMoveData((Ptr)nextFAT, (Ptr)FAT, NoGlueGetHandleSize(fond) - ((char*)nextFAT - (char*)fam));
- if (fam->ffWTabOff)
- fam->ffWTabOff -= bytesInAFATRecord;
- if (fam->ffKernOff)
- fam->ffKernOff -= bytesInAFATRecord;
- if (fam->ffStylOff)
- fam->ffStylOff -= bytesInAFATRecord;
- }
-
- /************************
-
- FDBFONDReferencesFont:
-
- Return a copy of the FOND (as a handle, not a resource), that has its FAT trimmed to refer to only
- those strikes (sfnt, nfnt) that are needed for the list of gxFonts. Nil means we don't need the FOND.
-
- We remove any sfnts that are not referenced, but leave any and all nfnts, since we don't know which
- were used in QD (since we don't know what point size(s) were used.
-
- May return fondCopy = nil, since the fonts may be application specific sfnts, and not have a corresponding
- quickdraw FOND.
-
- *************************/
- static OSErr FDBFONDReferencesFont(Handle fond, int fontCount, const fontSfntMap fontList[], Handle* fondCopy)
- {
- OSErr status = 0;
- Boolean match = false;
-
- *fondCopy = nil;
- if (*(short*)((FamRec*)*fond + 1) < 0) /* the FAT is empty */
- return status;
-
- while (fontCount-- > 0)
- { gxFontStorageTag storage;
- gxFontStorageReference reference;
- gxFontFormatTag format;
- gxFont fontID;
-
- fontID = fontList->fontID;
- storage = GXGetFont(fontID, &reference, nil);
- format = GXGetFontFormat(fontID);
- if (format == nfntFontFormatTag)
- { FamRec fam;
-
- if (GXFindFontTableParts(fontID, 'FOND', 0, sizeof(FamRec), &fam, nil) > 0)
- { if (fam.ffFamID == ((const FamRec*)*fond)->ffFamID)
- { status = CopyResourceToHandle(&fond);
- nrequire(status, failed_copy_resource_to_handle);
- AssertNoSfntReferences(fond);
- *fondCopy = fond;
- return status;
- }
- }
- }
- else if (storage == gxResourceFontStorage)
- { short rsrcID;
- OSType unusedTypeID;
- Str255 unusedName;
- short* FAT = (short*)((const FamRec*)*fond + 1);
- int FATCountBase0 = *FAT++;
-
- GetResInfo((Handle)reference, &rsrcID, &unusedTypeID, unusedName);
- status = ResError();
- nrequire(status, failed_get_res_info);
-
- while (FATCountBase0-- >= 0)
- { if (FAT[pointSizeIndex] == 0)
- { if (FAT[rsrcIDIndex] == rsrcID)
- { if (match == false)
- { long offset = (char*)FAT - (char*)*fond;
- status = CopyResourceToHandle(&fond);
- nrequire(status, failed_copy_resource_to_handle);
- FAT = (short*)((char*)*fond + offset);
- match = true;
- }
- FAT[pointSizeIndex] = kTakeThisSfntResource;
- FAT[rsrcIDIndex] = fontList->newSfntRsrcID;
- break;
- }
- }
- else if (FAT[pointSizeIndex] != kTakeThisSfntResource)
- break; /* stop when we've seen all the 'sfnt' resources */
- FAT += shortsInAFATRecord;
- }
- }
- ++fontList;
- }
-
- if (match)
- { short* FAT = (short*)((FamRec*)*fond + 1);
- int FATCountBase0 = *FAT++;
- long reduce = 0;
-
- while (FATCountBase0-- >= 0)
- { if (FAT[pointSizeIndex] == 0) /* an sfnt that we did NOT flag */
- {
- //dprintf(notrace, "deleting FAT [%d %d %d]", FAT[0], FAT[1], FAT[2]);
- FDBDeleteFATEntry(fond, FAT);
- reduce += bytesInAFATRecord;
- }
- else if (FAT[pointSizeIndex] == kTakeThisSfntResource)
- { FAT[pointSizeIndex] = 0; /* restore the 0-point size for 'sfnt's */
- FAT += shortsInAFATRecord;
- }
- else
- { ASSERT(FAT[pointSizeIndex] > 0, "assumed the was an NFNT fat");
- break; /* an NFNT means we're done deleting */
- }
- }
- if (reduce)
- PrSetHandleSize(fond, NoGlueGetHandleSize(fond) - reduce);
- *fondCopy = fond;
- }
-
- failed_get_res_info:
- failed_copy_resource_to_handle:
- return status;
- }
-
- /****************************
-
- FDBListOfReferencedFONDs:
-
- Takes an array of fontSfntMap records, and returns an array of FOND handles that reference
- the gxFonts in the records.
-
- ******************************/
- OSErr _FDBListOfReferencedFONDs(long fontCount, const fontSfntMap fontList[], long* FONDCount, Handle* FONDListPtr)
- {
- OSErr status;
- Handle FONDList;
- int rsrcCount, index;
-
- *FONDCount = 0;
- rsrcCount = CountResources('FOND');
- status = ResError();
- nrequire(status, failed_count_resources);
- status = PrNewHandle(&FONDList, rsrcCount * sizeof(Handle)); /* worst case */
- nrequire(status, failed_new_handle);
-
- for (index = 1; index <= rsrcCount; index++)
- { Handle fond = GetIndResource('FOND', index);
-
- status = ResError();
- nrequire(status, failed_get_ind_resource);
- do {
- Handle fondCopy;
-
- status = FDBFONDReferencesFont(fond, fontCount, fontList, &fondCopy);
- nrequire(status, failed_fond_references_font);
- if (fondCopy)
- GetHandleArray(FONDList, (*FONDCount)++) = fondCopy;
- } while (fond = XGetNextFOND(fond));
- }
- if (*FONDCount > 0)
- PrSetHandleSize(FONDList, *FONDCount * sizeof(Handle)); /* shrink it back down */
- else
- { PrDisposeHandle(FONDList);
- FONDList = nil;
- }
- *FONDListPtr = FONDList;
- return status;
-
- failed_get_ind_resource:
- failed_fond_references_font:
- for (index = 0; index < *FONDCount; index++)
- PrDisposeHandle(GetHandleArray(FONDList, index));
- PrDisposeHandle(FONDList);
- failed_new_handle:
- failed_count_resources:
- return status;
- }
-
- static OSErr WriteAndMarkPurgeable(Handle rsrc)
- {
- check( HGetState( rsrc ) & 0x20 );
- SetResAttrs(rsrc,GetResAttrs(rsrc) | resPurgeable);
- WriteResource(rsrc);
- return ResError();
- }
-
- /****************************
-
- FDBAddFONDsToResourceFile:
-
- Takes an array of FOND handles in FONDList, and addes them to the file theFile.
- It also adds any 'NFNT' and 'FONT' resources that are referenced by each FOND.
- It does NOT add the 'sfnt' that are referenced, since they are assumed to have
- been previously added.
-
- ******************************/
- OSErr _FDBAddFONDsToResourceFile(long FONDCount, Handle FONDList, gxSpoolFile theFile, Boolean useMessages)
- {
- int index;
- OSErr status;
-
- for (index = 0; index < FONDCount; index++)
- { const Handle fond = GetHandleArray(FONDList, index);
- const short* FAT = (short*)((const FamRec*)*fond + 1);
- int FATCountBase0 = *FAT++;
-
- HLock(fond);
- while (FATCountBase0-- >= 0)
- { if (FAT[pointSizeIndex] > 0)
- { Handle strike;
-
- if (!(strike = GetResource('NFNT', FAT[rsrcIDIndex])))
- strike = GetResource('FONT', FAT[rsrcIDIndex]);
- if (strike)
- { status = CopyResourceToHandle(&strike);
- nrequire(status, failed_copy_resource_to_handle);
-
- HNoPurge(strike);
- if (useMessages)
- status = Send_GXSpoolResource(theFile, strike, 'NFNT', FAT[rsrcIDIndex]);
- else
- status = FHAddResource( (TFile)theFile, strike, 'NFNT', FAT[rsrcIDIndex]);
- nrequire(status, failed_add_resource_nfnt);
- status = WriteAndMarkPurgeable(strike);
- nrequire(status, failed_add_resource_nfnt);
- }
- }
- FAT += shortsInAFATRecord;
- }
- HUnlock(fond);
- if (useMessages)
- status = Send_GXSpoolResource(theFile, fond, 'FOND', ((FamRec*)*fond)->ffFamID);
- else
- status = FHAddResource( (TFile)theFile, fond, 'FOND', ((FamRec*)*fond)->ffFamID);
- nrequire(status, failed_add_resource_fond);
- status = WriteAndMarkPurgeable(fond);
- nrequire(status, failed_add_resource_fond);
- }
- failed_add_resource_nfnt:
- failed_copy_resource_to_handle:
- failed_add_resource_fond:
- PrDisposeHandle(FONDList);
- return status;
- }
-
- #endif
-
- /****************************
-
- FDBComputeEntrySize:
-
- Computes the size of the variable length poriton
- of a font database entry. This added to
- sizeof(TFDBEntry) is the total size of the
- entry
-
- ******************************/
- long FDBComputeEntrySize(gxFlatFontListItem *theEntry);
- long FDBComputeEntrySize(gxFlatFontListItem *theEntry)
- {
- long entrySize;
-
- entrySize = 4 * ((theEntry->length + 3) / 4) + // the name size long alligned.
- (theEntry->variationCount + 1) * (4 * ((theEntry->glyphCount + 31) / 32)) + // All of the bit arrays (main + each variation)
- theEntry->variationCount * theEntry->axisCount * sizeof(gxFontVariation); // all of the axis values.
-
- return(entrySize);
-
- }//FDBComputeEntrySize
-
-
-
- //<FF>
- /****************************
- FDBEqualVariations:
-
- Test two varations for equality
-
- num: number of axes
- v1: pointer to 1st coordinates
- v2: pointer to 2nd coordinates
-
- ******************************/
- Boolean FDBEqualVariations(long num, gxFontVariation* v1, gxFontVariation* v2);
- Boolean FDBEqualVariations(long num, gxFontVariation* v1, gxFontVariation* v2)
- {
- register short idx;
-
- for (idx = num - 1; idx >= 0; --idx) {
- if ((v1->name != v2->name) || (v1->value != v2->value) ) {
- return(false);
- }//end if
- ++v1;
- ++v2;
- }//end for
- return(true);
-
- }//FDBEqualVariations
-
-
-
-
-
- //<FF>
- /************************************************
-
- Function: FDBAddVariationBitPair
-
- Function adds a new variation/bit pair to a
- document font database entry.
-
- hDbase: handle to the document font database
- entryOffset: Offset to the entry to modify
- newCoordinate: The new coordinate to add
- newBits: The new glyph bits to add.
-
- **************************************************/
- OSErr FDBAddVariationBitPair(TFontDbaseHdl hDbase, long entryOffset, gxFontVariation* newCoordinate, unsigned long* newBits);
- OSErr FDBAddVariationBitPair(TFontDbaseHdl hDbase, long entryOffset, gxFontVariation* newCoordinate, unsigned long* newBits)
- {
- OSErr status;
- TFDBEntry *theEntry;
- long axisCount;
- long glyphBitSize;
- long oldSize, additionalSize, sizeToSlide, entrySize, offset;
- unsigned char *start;
- long i, n;
-
-
- //dprintf(trace, "EntryOffset: %d", entryOffset);
-
- theEntry = (TFDBEntry*)( (long)(*hDbase)->fontDbaseInfo + entryOffset);
- axisCount = theEntry->fontInfo.axisCount;
- glyphBitSize = 4 * ((theEntry->fontInfo.glyphCount + 31) / 32);
-
- //dprintf(trace, "axisCount: %d, glyphBitSize: %d, #instances %d", axisCount, glyphBitSize, theEntry->fontInfo.variationCount);
-
- /**** Grow the font database handle to accomodate the new data *****/
-
- oldSize = sizeof(TFontDbaseRec) + (*hDbase)->nextOffset;
- additionalSize = axisCount * sizeof(gxFontVariation) + glyphBitSize;
-
- //dprintf(trace, "old size: %d, additinal size: %d", oldSize, additionalSize);
-
- status = PrSetHandleSize((Handle)hDbase, oldSize + additionalSize);
- nrequire(status, failed_SetSize);
-
- /****************
- Now slide all entries after the one we are adding
- to down to make room for new data
- *****************/
-
- /* Compute the start address of the data to slide, theEntry + size of the entry */
-
- theEntry = (TFDBEntry*)( (long)(*hDbase)->fontDbaseInfo + entryOffset);
-
- entrySize = sizeof(TFDBEntry) + FDBComputeEntrySize(&(theEntry->fontInfo));
-
-
- start = (unsigned char*)(theEntry) + entrySize;
-
- /* Slide the data */
-
- sizeToSlide = (*hDbase)->nextOffset - (entryOffset + entrySize);
- //dprintf(trace, "entrySize: %d, sizeToSlide %d", entrySize, sizeToSlide);
- if (sizeToSlide > 0)
- BlockMoveData((Ptr)start, (Ptr)(start + additionalSize), sizeToSlide);
-
-
- /******
- Now actually copy the new data into our entry
- ******/
-
- /* Start is pointing to where to put the new data */
-
- theEntry->fontInfo.variationCount += 1;
-
- //dprintf(notrace, "newBits: %X, newCoordinate: %X", newBits, newCoordinate);
- BlockMoveData((Ptr)newBits, (Ptr)start, glyphBitSize);
- BlockMoveData((Ptr)newCoordinate, (Ptr)(start + glyphBitSize), axisCount * sizeof(gxFontVariation));
-
-
- /*******
- Update the offset collection:
- any entries after the current one
- must have the additionalSize added to their
- offsets stored in the collection
- *******/
-
- n = (*hDbase)->numFonts;
- for (i = 1; i <= n; ++i) {
-
- /** Get the offset of the next entry **/
-
- status = GetIndexedCollectionItem((*hDbase)->docFonts, i, nil, &offset);
- nrequire(status, failed_GetItem);
-
- /** If the offset is greater than the entries offset then it must be updated **/
-
- if (offset > entryOffset) {
-
- offset += additionalSize; // update the value
-
- status = ReplaceIndexedCollectionItem((*hDbase)->docFonts, i, sizeof(long), &offset);
- nrequire(status, failed_ReplaceItem);
-
- }//end if
-
- }//end for
-
- /** Now update the rest of the database record **/
-
- (*hDbase)->nextOffset += additionalSize; // move the next available offset
-
-
- failed_ReplaceItem:
- failed_GetItem:
- failed_SetSize:
-
- return(status);
-
-
- }//FDBAddVariationBitPair
-
- //<FF>
- /************************************************
-
- Function: FDBUnionEntry
-
- Function unions a new page database tag (flatFontList)
- with the one stored in the database.
-
- *************************************************/
- OSErr FDBUnionEntry(TFontDbaseHdl hDbase, long entryOffset, gxFlatFontListItem *pageDbase);
- OSErr FDBUnionEntry(TFontDbaseHdl hDbase, long entryOffset, gxFlatFontListItem *pageDbase)
- {
- long i, j;
- register short numLongs;
- OSErr status = noErr;
- unsigned char *pDoc, *pPage; // point into stuff for doc and page.
- TFDBEntry *theEntry; // the entry to union pageDbase with.
- long uniqueNameL; // the long alligned number of bytes in the name.
- unsigned long *docBits, *pageBits; // the document glyph bits and the page glyph bits.
- long glyphBitSize; // number of bytes in bit array.
- gxFontVariation *pageCoordinate, // coordinate from the page database
- *docCoordinate; // coordinate from the doc database.
- long axisCount;
-
- axisCount = pageDbase->axisCount;
- uniqueNameL = 4 * ((pageDbase->length + 3) / 4);
- glyphBitSize = 4 * ((pageDbase->glyphCount + 31) / 32);
-
- /** First union the main bit array **/
-
- pDoc = (unsigned char*)((long)(*hDbase)->fontDbaseInfo + entryOffset); // point pDoc at entry.
- docBits = (unsigned long*)(pDoc + sizeof(TFDBEntry) + uniqueNameL); // offset from pDoc to bits.
- pageBits = (unsigned long*)( (long)pageDbase + sizeof(gxFlatFontListItem) + uniqueNameL); // Point to page bits
-
- //dprintf(notrace, "font: %d, docBits: %X, pageBits: %X", pageDbase->fontID, docBits, pageBits);
-
- for (numLongs = glyphBitSize/4 - 1; numLongs >= 0; --numLongs)
- *docBits++ |= *pageBits++;
-
-
- /***************
-
- Now union all fo the bits/Variation pairs,
- add any new pairs necessary.
-
- ****************/
-
- /* point pPage at first bits/variations pair in page database */
-
- pPage = (unsigned char*)((long)pageDbase + sizeof(gxFlatFontListItem) + uniqueNameL + glyphBitSize);
-
- /** Loop through the bit/variation pairs in the page **/
-
- for (i = 0; i < pageDbase->variationCount; ++i) {
-
- pageBits = (unsigned long*)pPage;
- pageCoordinate = (gxFontVariation*)(pPage + glyphBitSize);
-
- pDoc = (unsigned char*)((long)(*hDbase)->fontDbaseInfo + entryOffset);
- theEntry = (TFDBEntry*)(pDoc);
-
- /* point at first pair in document entry */
- pDoc += sizeof(TFDBEntry) + uniqueNameL + glyphBitSize;
-
- /* Loop through the document pairs to find match */
-
- for (j = 0; j < theEntry->fontInfo.variationCount; ++j) {
-
- docCoordinate = (gxFontVariation*)(pDoc + glyphBitSize);
-
- if (FDBEqualVariations(axisCount, docCoordinate, pageCoordinate)) {
-
- /* If we found a match, union the bits */
- docBits = (unsigned long*)pDoc;
- for (numLongs = glyphBitSize/4 - 1; numLongs >= 0; --numLongs)
- *docBits++ |= *pageBits++;
-
- break;
-
- }//end if
-
- /* point to next pair in doc entry */
-
- pDoc += glyphBitSize + axisCount * sizeof(gxFontVariation);
-
- }//end for
-
- /* if we didn't get a match, add the new pair to the document entry */
- if (j >= theEntry->fontInfo.variationCount) {
-
- status = FDBAddVariationBitPair(hDbase, entryOffset, pageCoordinate, pageBits);
- nrequire(status, failed_AddPair);
-
- }//end if
-
- /* point to next pair in page. */
-
- pPage += glyphBitSize + axisCount * sizeof(gxFontVariation);
-
- }//end for
-
-
- failed_AddPair:
-
- return(status);
-
- }//FDBUnionEntry
-
-
- //<FF>
- /**********************************
-
- Function: FDBSetMac8bitEncodingGlyphs
-
- Function takes the glyph bits from the tag
- and sets them up to reflect the 8 bit Macintosh
- encoding for the current system.
-
- ***********************************/
- OSErr FDBSetMac8bitEncodingGlyphs(gxFlatFontListItem *pageDbase);
- OSErr FDBSetMac8bitEncodingGlyphs(gxFlatFontListItem *pageDbase)
- {
- OSErr status;
- long uniqueNameLengthL;
- long *pageBits;
- unsigned short *aGlyphCode, *theGlyphCodes;
- register short i;
- Handle h;
- long length;
-
- uniqueNameLengthL = 4 * ((pageDbase->length + 3) / 4);
- pageBits = (long*)((long)pageDbase + sizeof(gxFlatFontListItem) + uniqueNameLengthL);
-
- status = PrNewHandle(&h, 256 * sizeof(unsigned short));
- nrequire(status, failed_alloc);
- HLock(h);
-
- theGlyphCodes = (unsigned short*)*h;
-
- length = MakeMac8BitEncoding(pageDbase->fontID, theGlyphCodes);
- check(length == 256);
-
- /** Now go and set all of the bits for the glyphs that came back **/
-
- aGlyphCode = theGlyphCodes;
- for (i = 255; i != -1; --i) {
-
- if (*aGlyphCode <= pageDbase->glyphCount) {
-
- BITSET(pageBits, *aGlyphCode);
-
- } else {
-
- #if DEBUGLEVEL > 0
- dprintf(trace, "asked to encode glyph: %d, outside of font's range of %d", *aGlyphCode, pageDbase->glyphCount);
- #endif
-
- }//end if
-
- ++aGlyphCode;
-
- }//end for
-
- /** Set the bits for the first snapshot also (to help apps like freehand) **/
-
- if (pageDbase->variationCount >= 1) {
-
- /* Skip to the first bit/variation combo, which is right after the main bit array */
- pageBits = (long*)((unsigned char*)pageBits + 4 * ((pageDbase->glyphCount + 31) / 32));
-
- /* Evil code, should modularize -- Keep in sync with copy above !!!*/
- aGlyphCode = theGlyphCodes;
- for (i = 255; i != -1; --i) {
-
- if (*aGlyphCode <= pageDbase->glyphCount) {
-
- BITSET(pageBits, *aGlyphCode);
-
- } else {
-
- #if DEBUGLEVEL > 0
- dprintf(trace, "asked to encode glyph: %d, outside of font's range of %d", *aGlyphCode, pageDbase->glyphCount);
- #endif
-
- }//end if
-
- ++aGlyphCode;
-
- }//end for
-
- }//end if
-
- DisposeHandle(h);
-
- failed_alloc:
- return(status);
-
- }//FDBSetMac8bitEncodingGlyphs
- //<FF>
- /**********************************
-
- Function: FDBAddEntry:
-
- Function adds a page database to the document database.
- Data is stored at the end. Handle is grown to accomodate new data.
-
- hDbase: handle to the font database record.
- pageFontTag: the tag from the page. Assumed to be locked.
- useMac8bitEncoding: bolean indicates whether or not to set flag for using 8bit encoding.
- ************************************/
- OSErr FDBAddEntry(TFontDbaseHdl hDbase, gxFlatFontListItem *dBaseEntry, Boolean useMac8bitEncoding);
- OSErr FDBAddEntry(TFontDbaseHdl hDbase, gxFlatFontListItem *dBaseEntry, Boolean useMac8bitEncoding)
- {
- OSErr status;
- long newSize; // new size for database handle.
- long entrySize; // size of unique name plus glyph bits and variation bits.
- TFontDbasePtr pDbase;
- TFDBEntry *newEntry;
- long offset;
-
- pDbase = *hDbase;
-
- /** Compute the size of the variable length portion of the flatFontListItem **/
-
- entrySize = FDBComputeEntrySize(dBaseEntry);
-
- newSize = sizeof(TFontDbaseRec) + pDbase->nextOffset + sizeof(TFDBEntry) + entrySize;
-
- status = PrSetHandleSize((Handle)hDbase, newSize);
- nrequire(status, failed_SetSize);
-
- pDbase = *hDbase; // may have moved when setting size.
-
- /** Copy the current page number and the data from the tag into the database **/
-
- newEntry = (TFDBEntry*)((long)&(pDbase->fontDbaseInfo) + pDbase->nextOffset);
- newEntry->firstPage = pDbase->currPage;
-
- if (useMac8bitEncoding)
- newEntry->flags = fdbUseMac8Bit;
- else
- newEntry->flags = 0;
-
- memcpy( &(newEntry->fontInfo), dBaseEntry, sizeof(gxFlatFontListItem) + entrySize);
-
- /** Store the offset in the collection: data is offset, collection tag is font. **/
-
- offset = pDbase->nextOffset;
- status = AddCollectionItem( pDbase->docFonts,
- (CollectionTag)dBaseEntry->fontID, // the collection tag is the font ID
- nil, // id nil.
- sizeof(long), // data is a long.
- &offset); // data.
- nrequire(status, failed_AddCollection);
-
- /** Update the offset for writing the next entry **/
-
- pDbase = *hDbase; // may have moved when adding collection item.
-
- pDbase->nextOffset += sizeof(TFDBEntry) + entrySize;
- ++(pDbase->numFonts);
-
- failed_AddCollection:
- failed_SetSize:
- return(status);
-
- }//FDBAddEntry
-
-
- //<FF>
- /****************************************
-
- Function: FDBSetGlyphBits.
-
- Function sets the glyph bits for the glyphs passed in.
- If the glyphs array is nil, all bits are set.
-
- bits: target bit array. (Must be big enough to hold largest glyph index)
- glyphBitSize: size of bit array in bytes.
- numGlyphs: number of glyphs.
- glyphs: array of glyph codes to set. If nil, all bits are set.
-
- ****************************************/
- void FDBSetGlyphBits(unsigned char *bits, long glyphBitSize, long numGlyphs, unsigned short glyphs[]);
- void FDBSetGlyphBits(unsigned char *bits, long glyphBitSize, long numGlyphs, unsigned short glyphs[])
- {
- unsigned short *aGlyph;
- long i;
- long glyphCode;
-
- check(bits);
-
- if (glyphs == nil) {
-
- memset(bits, 0xFF, glyphBitSize);
-
- } else {
-
- memset(bits, 0x00, glyphBitSize);
-
- aGlyph = glyphs;
- for (i = 0; i < numGlyphs; ++i) {
-
- glyphCode = *aGlyph++;
-
- #if DEBUGLEVEL > 0
- if (glyphCode >= glyphBitSize * 8)
- dprintf(notrace, "Fatal error: glyph code: %d", glyphCode);
- #endif
-
- BITSET(bits, glyphCode);
-
- }//end for
-
- }//end if
-
- }//FDBSetGlyphBits
-
-
-
- //<FF>
- /*******************************************************
-
- Function: FontDbaseAddStyleEntry
-
- Function adds an entry to the database for the style and
- glyphs passed in. This is used to build entries for the default
- font (for font substitution) as well as for QD shapes.
-
- fontDbase: a font database object.
- theStyle: Style containing font and variations for the entry.
- numGlyphs: number of glyphs in array.
- glyphs: array of glyphs to set bits for. (If nil, set all bits)
- use8BitMacEncoding: use 8 bit encoding?
-
- *********************************************************/
- OSErr FontDbaseAddStyleEntry(TFontDbase fontDbase, gxStyle theStyle, long numGlyphs, unsigned short glyphs[], Boolean use8BitMacEncoding)
- {
- OSErr status;
- Handle hItem;
- gxFlatFontListItem *item;
- long size;
- long glyphCount;
- long axisCount;
- long nameLength; // length of font name.
- long nameLengthL; // long alligned name length;
- gxFont theFont;
- long glyphBitSize;
- unsigned char* bits; // I know, generally a long but this makes ptr math easier.
- gxFontVariation *variations;
- gxFontName name;
- gxFontPlatform platform;
- gxFontScript script;
- gxFontLanguage language;
- long nameIndex;
-
- theFont = GXGetStyleFont(theStyle);
-
- glyphCount = GXCountFontGlyphs(theFont);
- axisCount = GXCountFontVariations(theFont);
- glyphBitSize = 4 * ((glyphCount + 31) / 32);
-
- /* figure out the size of the item */
-
- size = sizeof(gxFlatFontListItem) + glyphBitSize;
-
- /* if it is a variation font, make room for a variation/bit pair */
- if (axisCount > 0)
- size += glyphBitSize + axisCount * sizeof(gxFontVariation);
-
- /* Add in space for the name (Unique name, if none use PostScript name */
- nameLength = GXFindFontName(theFont, gxUniqueFontName, gxNoPlatform, gxNoScript, gxNoLanguage, nil, &nameIndex);
- if (nameLength == 0)
- nameLength = GXFindFontName(theFont, gxPostscriptFontName, gxNoPlatform, gxNoScript, gxNoLanguage, nil, &nameIndex);
- nameLengthL = 4 * (( nameLength + 3) / 4);
-
- size += nameLengthL;
-
- /* Get memory for the item */
-
- status = PrNewHandle(&hItem, size);
- nrequire(status, failed_alloc);
- HLock(hItem);
- item = (gxFlatFontListItem*)(*hItem);
-
- /* Now fill in the primary fields of the item */
-
- item->fontID = theFont;
-
- /*** Fill in the unique name field ***/
-
- item->length = nameLength;
- GXGetFontName(theFont, nameIndex, &name, &platform, &script, &language,
- (unsigned char*)(item) + sizeof(gxFlatFontListItem));
-
- item->name = name; item->script = script; item->language = language; item->platform = platform;
-
- check(name == gxUniqueFontName);
-
- /* fill in the variation/glyph information */
- item->glyphCount = glyphCount;
- item->axisCount = axisCount;
- if (axisCount)
- item->variationCount = 1; // allow for one (default) variation/bit pair.
- else
- item->variationCount = 0;
-
- /* Fill in the primary glyph bits */
- bits = (unsigned char*)item + sizeof(gxFlatFontListItem) + nameLengthL;
- FDBSetGlyphBits(bits, glyphBitSize, numGlyphs, glyphs);
-
- /* Fill in variation/bit pair if necessary */
- if (axisCount > 0) {
-
- /* Point to the first bit array in the pairs. (its right after main bits) */
- bits += glyphBitSize;
- FDBSetGlyphBits(bits, glyphBitSize, numGlyphs, glyphs);
-
- /* point to variations */
- variations = (gxFontVariation*)(bits + glyphBitSize);
-
- /* Fill in the variations */
-
- GXSetStyleFont(theStyle, theFont);
- GXGetStyleFontVariationSuite(theStyle, variations);
-
- }//end if
-
- /** Now add the item to the database **/
-
- status = FontDbaseAddItem(fontDbase, item, use8BitMacEncoding);
- ncheck(status);
-
- DisposeHandle(hItem);
-
-
- failed_alloc:
- return(status);
-
- }//_FontDbaseAddStyleEntry
-
-
-
-
- //<FF>
- /*******************************************************
-
- Function: FDBAddDefaultFontEntry
-
- Function adds an entry to the database for the GX default
- font. The entry will have all of the glyph bits set.
- This is used so font substitution works.
-
- All of the bits are set because we don't know in advance
- what glyphs will be used.
-
- *********************************************************/
- OSErr FDBAddDefaultFontEntry(TFontDbaseHdl hDbase, Boolean use8BitMacEncoding);
- OSErr FDBAddDefaultFontEntry(TFontDbaseHdl hDbase, Boolean use8BitMacEncoding)
- {
- OSErr status;
- gxStyle theStyle;
-
-
- /* Get the default style, give it default font */
-
- theStyle = GXNewStyle();
- GXSetStyleFont(theStyle, GXGetDefaultFont());
-
- status = FontDbaseAddStyleEntry((TFontDbase)hDbase, theStyle, 0, nil, use8BitMacEncoding);
- ncheck(status);
-
- GXDisposeStyle(theStyle);
-
- return(status);
-
- }//FDBAddDefaultFontEntry
-
- //<FF>
- /*******************************************************
-
- Function: FDBBuildOffsetCollection
-
- Function builds the collections that map from font ID's
- to offsets into the database. This is done by finding the
- font ID that corresponds to the name stored in the database.
-
-
- It is assumed that there is no collection in the font database
- record. The handle should contain a valid numFonts and fontDbaseInfo.
-
- ********************************************************/
-
- OSErr FDBBuildOffsetCollection(TFontDbaseHdl hDbase);
- OSErr FDBBuildOffsetCollection(TFontDbaseHdl hDbase)
- {
- OSErr status = noErr;
- long i;
- TFontDbasePtr pDbase;
- gxFont fontID; // the font reference.
- unsigned char *fontName; // Name of the current font.
- TFDBEntry *dBaseEntry; // An entry in the database.
- long offset; // offset into data for an entry.
- Boolean fontSubstitution; // Do we need font substitution?
- long fontCount; // Number of legal (non-substituted fonts) in database.
- Boolean useMac8BitEncoding; // Use 8 bit encoding for default font.
-
- useMac8BitEncoding = false;
- HLock((Handle)hDbase);
- pDbase = *hDbase;
-
- fontSubstitution = false; // initialize to no substitution necessary.
-
- /** Allocate the collection **/
-
- require_action(pDbase->docFonts = NewCollection(), failed_Collection, status = MemError(););
-
- /************************
- Now loop through the data to find id's corresponding to the fonts
- and store the offsets into the database in the collection
- *************************/
- offset = 0;
- fontCount = 0;
- for (i = 0; i < pDbase->numFonts; ++i) {
-
- dBaseEntry = (TFDBEntry*)((long)&(pDbase->fontDbaseInfo) + offset);
-
- fontName = (unsigned char*)((long)&(dBaseEntry->fontInfo) + sizeof(gxFlatFontListItem)); // The name is first field at end of record.
-
-
- /** Find the font id corresponding to the name, if it's not there, turn on substitution **/
-
- if (GXFindFonts(0,
- dBaseEntry->fontInfo.name,
- dBaseEntry->fontInfo.platform,
- dBaseEntry->fontInfo.script,
- dBaseEntry->fontInfo.language,
- dBaseEntry->fontInfo.length, &fontName[0], 1, 1, &fontID) == 0) {
-
- fontSubstitution = true; // turn on font substitution.
- if (dBaseEntry->flags & fdbUseMac8Bit)
- useMac8BitEncoding = true;
-
- #if DEBUGLEVEL >= DEBUGFEEDBACK
- dprintf(trace, "Font Substitution For: %s", fontName);
- #endif
-
- } else {
-
- /*** Add the font to the collection **/
-
- status = AddCollectionItem( pDbase->docFonts,
- (CollectionTag)fontID, // the collection tag is the font ID
- nil, // id nil
- sizeof(long), // the data is the offset, a long.
- &offset);
- nrequire(status, failed_AddCollection);
-
- fontCount += 1; // this will be the number we successfuly found.
-
- }//end if
-
- dBaseEntry->fontInfo.fontID = fontID;
-
- /** Add the size of the entry to the current offset **/
-
- offset += sizeof(TFDBEntry) + FDBComputeEntrySize(&(dBaseEntry->fontInfo));
-
- }//end for
-
- pDbase->nextOffset = offset;
- pDbase->numFonts = CountCollectionItems(pDbase->docFonts); // reset the number of fonts to match collection
-
- #if DEBUGLEVEL > 0
- if (fontCount != pDbase->numFonts)
- dprintf(notrace, "Warning, you have more than 1 font with same unique name - performance may suffer");
- #endif
-
- failed_AddDefault:
- failed_AddCollection:
- failed_Collection:
-
- HUnlock((Handle)hDbase);
-
-
- /*******
- If there was no error but we need font substitution,
- add a database entry for the default font.
- This will ensure that clients know the document
- uses whatever font the default is
- ********/
- if ( (status == noErr) && fontSubstitution) {
-
- status = FDBAddDefaultFontEntry(hDbase, useMac8BitEncoding);
- ncheck(status);
-
- }//end if
-
- return(status);
-
- }//FDBBuildOffsetCollection
-
- //<FF>
- /*************************************
-
- Function: FDBReadSpoolFileFonts
-
- Function reads in fonts from spool file.
- Unfortunately, there is no good way for this to
- work through messaging. If there ever is, we'll
- fix it.
-
- **************************************/
- OSErr FDBReadSpoolFileFonts(TFontDbaseHdl hDbase);
- OSErr FDBReadSpoolFileFonts(TFontDbaseHdl hDbase)
- {
- OSErr status = noErr;
- Handle hFileFonts; // handle full of font references from file.
- Handle sfnt; // An sfnt resource.
- long count, numLoaded;
- long i;
- gxFont *aFont;
- char resLoadState = *(char*)0xa5e; /* stolen from graphics toolbox library.c */
-
- count = Count1Resources('sfnt'); // find out how many.
-
- if (count == 0) {
-
- (*hDbase)->numFileFonts = 0;
- (*hDbase)->hFileFonts = nil;
- return(noErr);
-
- }//end if
-
- /** Allocate a handle for the font list **/
-
- status = PrNewHandle(&hFileFonts, count * sizeof(gxFont));
- nrequire(status, failed_alloc);
-
- SetResLoad(false);
- HLock(hFileFonts);
- aFont = (gxFont*)*hFileFonts;
- numLoaded = 0;
- for (i = 1; i <= count; ++i) {
-
- sfnt = Get1IndResource('sfnt', i);
- require(sfnt, failed_font);
-
- *aFont++ = GXNewFont(gxResourceFontStorage, sfnt, 0);
- status = GXGetGraphicsError(nil);
- nrequire_action(status, failed_newFont, ReleaseResource(sfnt););
-
- numLoaded += 1; // In case we have to clean up.
-
- }//end for
-
- HUnlock(hFileFonts);
- SetResLoad(resLoadState);
-
-
- (*hDbase)->numFileFonts = count;
- (*hDbase)->hFileFonts = hFileFonts;
-
- return(noErr);
-
- /****** exception handling ********/
-
- failed_newFont:
- failed_font:
-
- status = MemError(); // find out why we failed to load the font resource.
- if (status == noErr);
- status = ResError();
-
- ncheck(status);
-
-
- /* Get rid of any fonts that were loaded */
- aFont = (gxFont*)*hFileFonts;
- for (i = 1; i <= numLoaded; ++i);
- GXDisposeFont(*aFont++);
-
- DisposeHandle(hFileFonts);
-
- failed_alloc:
-
- SetResLoad(resLoadState);
- return(status);
-
- }//FDBReadSpoolFileFonts
-
-
- //<FF>
- /*************************************
-
- Function: FDBNewEmptyDatabase
-
- Function creates a new and empty font database object.
-
- **************************************/
- OSErr FDBNewEmptyDatabase(TFontDbase *fontDbase);
- OSErr FDBNewEmptyDatabase(TFontDbase *fontDbase)
- {
- OSErr status;
- TFontDbaseHdl hDbase;
-
- *fontDbase = nil;
-
- status = PrNewHandleClear((Handle*)&hDbase, sizeof(TFontDbaseRec));
- nrequire(status, failed_Alloc);
-
- /********
- From NewHandleClear:
- hFilefonts is nil,
- numFileFonts is 0,
- page count is 0,
- nextOffset is 0,
- numFonts is 0,
- currPage is 0,
- lockCount is 0
- prerequisites is nil.
- *********/
-
- (*hDbase)->dbaseVersion = fdbThisVersion;
-
- /** Allocate the collection for the database **/
-
- (*hDbase)->docFonts = NewCollection();
- require_action((*hDbase)->docFonts, failed_Collection, status = MemError(););
-
- *fontDbase = (TFontDbase)hDbase;
-
- failed_Collection:
- failed_Alloc:
- return(status);
-
- }//FDBNewEmptyDatabase
-
-
-
- //<FF>
- /*************************************
-
- Function: FontDbaseInit
-
- Function initializes the font database
-
- fontDbase: Handle allocated by this function containing the
- database.
-
- theFile: A spool file to read the font database from. If Nil is passed
- an empty font database is created. Pass Nil for creating the database
- Pass a file to read one in.
-
- useMessages: true to use messages to despool resource, false to call file handler directly.
-
- **************************************/
- OSErr FontDbaseInit(TFontDbase *fontDbase, gxSpoolFile* theFile)
- {
- OSErr status;
-
- if (theFile == nil) {
-
- status = FDBNewEmptyDatabase(fontDbase);
- nrequire(status, failed_Alloc);
-
- } else {
-
- /** Read the font database in from the spool file **/
-
- // Important change. Old GX code used messages to access the spool file. We use the spool file C++ class here.
- status = theFile->DespoolResource(kFontDbaseResType, printingBaseID, (Handle*)fontDbase);
-
- if (status == resNotFound) {
-
- /** If we could not read the resouce, just create an empty database **/
-
- #if DEBUGLEVEL > 1
- dprintf(trace, "Couldn't load font database resource, creating empty database");
- #endif
-
- status = FDBNewEmptyDatabase(fontDbase);
- nrequire(status, failed_Alloc1);
-
- } else {
-
- nrequire(status, failed_GetResource);
-
- HNoPurge((Handle)*fontDbase); // better not go away!
- DetachResource((Handle)*fontDbase); // Make it a regular handle.
-
- /** If we ever change it from a shipping version, put code in to read old versions **/
-
- if ( (*(TFontDbaseHdl)*fontDbase)->dbaseVersion != fdbThisVersion) {
-
- #if DEBUGLEVEL > 1
- dprintf(notrace, "Database version is invalid: %X", (*(TFontDbaseHdl)*fontDbase)->dbaseVersion);
- #endif
- status = -999;
- goto failed_version;
-
- }//endif
-
- }//end if
-
- /** Read in any fonts from the spool file **/
-
- status = FDBReadSpoolFileFonts((TFontDbaseHdl)*fontDbase);
- nrequire(status, failed_readFonts);
-
- /** Build the collection that Maps font ID's to offsets into handle **/
-
- status = FDBBuildOffsetCollection((TFontDbaseHdl)*fontDbase);
- ncheck(status);
-
- (*(TFontDbaseHdl)*fontDbase)->lockCount = 0;
- (*(TFontDbaseHdl)*fontDbase)->prerequisites = nil;
-
- }//end if
-
- failed_version:
- failed_readFonts:
-
- /** If there was an error after getting the handle, dispose of the handle before returning error **/
- if (status != noErr)
- DisposeHandle(*(Handle*)fontDbase);
-
- failed_Alloc1:
- failed_GetResource:
- failed_Collection:
- failed_Alloc:
- return(status);
-
- }//FontDbaseInit
-
-
-
- //<FF>
- /*************************************
-
- Function: FontDbaseShutdown
-
- Function deallocates the font database
- or writes it to a resource in the spool file
- if specified.
- If one is specified and the write fails
- then the handle is deallocated.
-
- fontDbase: The font database.
- theFile: Spool file to write database to. If Nil, database is not written.
-
- **************************************/
-
- OSErr FontDbaseShutdown(TFontDbase fontDbase, gxSpoolFile* theFile)
- {
- OSErr status = noErr;
- TFontDbasePtr pDbase;
- gxFont *aFont;
- Handle hFileFonts;
- long i;
-
- #ifdef test_FontDbaseUnion
- {
- TFontDbase target;
- status = _FontDbaseInit(&target, nil, false);
- ncheck(status);
- status = _FontDbaseUnion(fontDbase, target);
- ncheck(status);
- //dprintf(notrace, "source: %X, target: %X", *(TFontDbaseHdl)fontDbase, *(TFontDbaseHdl)target);
- if (theFile != nil)
- status = Send_GXSpoolResource(theFile, (Handle)target, kFontDbaseResType, 0);
- ncheck(status);
- }
- #endif
-
- /* Dispose of any fonts loaded in with this database */
-
- pDbase = *(TFontDbaseHdl)fontDbase;
- hFileFonts = pDbase->hFileFonts;
-
- if (hFileFonts != nil) {
-
- HLock(hFileFonts);
- aFont = (gxFont*)*hFileFonts;
- for (i = 0; i < pDbase->numFileFonts; ++i)
- GXDisposeFont(*aFont++);
-
- DisposeHandle(hFileFonts);
-
- }//end if
-
-
- /* Dispose of the offset collection */
-
- pDbase = *(TFontDbaseHdl)fontDbase;
- if (pDbase->docFonts != nil)
- DisposeCollection(pDbase->docFonts);
-
-
- /* Dispose of the prerequisite collection */
-
- pDbase = *(TFontDbaseHdl)fontDbase;
- if (pDbase->prerequisites != nil)
- DisposeCollection(pDbase->prerequisites);
-
- /** Write it out if to the resource of the spool file if specified **/
-
- if (theFile != nil) {
-
- // Important change: DL 7/26/97 Changing from using GX spool file messages to using spool file C++ class
- status = theFile->SpoolResource((Handle)fontDbase, kFontDbaseResType, printingBaseID);
- ncheck(status);
-
- }//end if
-
- /******
- Dispose of the handle if we failed to spool it as a resource
- or a spool file was not specified
- *****/
-
- if ( (theFile == nil) || (status != noErr)) {
-
- DisposeHandle((Handle)fontDbase);
-
- }//end if
-
- return(status);
-
- }//FontDbaseShutdown
-
-
-
- //<FF>
- /***************************************************
- FontDbaseSetFontFlags
-
- Set the flags for a particular font in the database.
-
- ****************************************************/
- OSErr FontDbaseSetFontFlags(TFontDbase fontDbase, gxFont fontID, TfdbInfoFlags flags)
- {
- OSErr status;
- long entryOffset; // Offset into handle.
- register unsigned char *p;
- register TFDBEntry *entry;
-
- status = GetCollectionItem((*(TFontDbaseHdl)fontDbase)->docFonts,
- (CollectionTag)fontID, // tag is the font id.
- nil,
- nil,
- &entryOffset);
- nrequire(status, failed_GetItem);
-
- p = (unsigned char*)((*(TFontDbaseHdl)fontDbase)->fontDbaseInfo) + entryOffset; // Point to entry.
- entry = (TFDBEntry*)(p);
- entry->flags = flags;
-
- failed_GetItem:
- return(status);
-
- }//FontDbaseSetFontFlags
-
-
- //<FF>
- /*************************************
-
- Function: FontDbaseAddItem
-
- Function unions a single flatFontListItem
- with the document font database.
-
- **************************************/
- OSErr FontDbaseAddItem(TFontDbase fontDbase, gxFlatFontListItem *item, Boolean useMac8bitEncoding)
- {
- OSErr status;
- long entryOffset; // offset into database.
-
-
- /** If we are told to just use the mac 8 bit encoding, set the glyph bits **/
-
- if (useMac8bitEncoding) {
-
- status = FDBSetMac8bitEncodingGlyphs(item);
- nrequire(status, failed_8bit);
-
- }//end if
-
- /*****
-
- Get the entry out of the database for the current font or add it
- if it does not exist
-
- ******/
-
- #if DEBUGLEVEL > 0
-
- /** To avoid annoying collection manager assertion in debugging version **/
-
- if (CollectionTagExists((*(TFontDbaseHdl)fontDbase)->docFonts, (CollectionTag)item->fontID) )
- status = GetCollectionItem((*(TFontDbaseHdl)fontDbase)->docFonts,
- (CollectionTag)item->fontID, // tag is the font id.
- nil,
- nil,
- &entryOffset);
- else
- status = collectionItemNotFoundErr;
- #else
- status = GetCollectionItem((*(TFontDbaseHdl)fontDbase)->docFonts,
- (CollectionTag)item->fontID, // tag is the font id.
- nil,
- nil,
- &entryOffset);
- #endif
-
- if ( (status == collectionItemNotFoundErr) || (status == collectionIndexRangeErr)) {
-
- /** If the item was not found, add a new entry to the database **/
-
- status = FDBAddEntry((TFontDbaseHdl)fontDbase, item, useMac8bitEncoding);
- nrequire(status, failed_AddEntry);
-
- } else if (status == noErr) {
-
- /** If an entry existed for this font, union the current item with the one we already have **/
-
- status = FDBUnionEntry((TFontDbaseHdl)fontDbase, entryOffset, item);
- nrequire(status, failed_Union);
-
- }//end if
-
- failed_Union:
- failed_AddEntry:
- failed_Collection:
- failed_8bit:
-
- return(status);
-
- }//FontDbaseAddItem
-
-
- //<FF>
- /*************************************
-
- Function: FontDbaseAddPage
-
- Function unions in the database from a shape into
- the document font database
-
- fontDbase: A valid document font database handle.
-
- thePage: the shape containing the page after it has been flattened
- so it has a valid font database tag.
-
- useMac8bitEncoding: true if you want to add all of the glyphs for the standard mac encoding
- rather than the glyphs that are in the document that are set.
-
- **************************************/
-
- OSErr FontDbaseAddPage( TFontDbase fontDbase, gxShape thePage, Boolean useMac8bitEncoding)
- {
- OSErr status = noErr;
- long i;
- long nFonts; // number of fonts used on the page.
- gxTag dBaseTag; // font database tag.
- gxFlatFontListItem *pageDbase; // Entry for a font from the page.
-
- ++((*(TFontDbaseHdl)fontDbase)->currPage); // Increment the current page.
-
- nFonts = GXGetShapeTags(thePage, gxFlatFontListItemTag, 1, gxSelectToEnd, nil);
-
- for (i = 1; (i <= nFonts) && (status == noErr); ++i) {
-
-
- /** Get the tag data for a font in the page **/
-
- GXGetShapeTags(thePage, gxFlatFontListItemTag, i, 1, &dBaseTag);
- GXLockTag(dBaseTag);
- nrequire(status = GXGetGraphicsError(nil), failed_GetAndLockTag);
-
- pageDbase = (gxFlatFontListItem*)GXGetTagStructure(dBaseTag, nil);
-
- status = FontDbaseAddItem(fontDbase, pageDbase, useMac8bitEncoding);
- nrequire(status, failed_AddItem);
-
- failed_AddItem:
-
- GXUnlockTag(dBaseTag);
-
- }//end for
-
- failed_GetAndLockTag:
-
- return(status);
-
- }//FontDbaseAddPage
-
-
-
- //<FF>
- /****************************************
-
- Function: FontDbaseGetFontInfo
-
- Function returns information about the font database
- entry. (Yes some of this could simply be obtained through
- standard gx font api, but this is a shortcut.
-
- fontDbase: The font database.
- fontID: The font to get info for.
- glyphCount: <-- Number of glyphs in font.
- axisCount: <-- Number of variation axes in font.
- variationCount: <-- Number of variation/bit pairs in database for the font.
- flags: <-- font database flags for this font.
-
- *******************************************/
- OSErr FontDbaseGetFontInfo(TFontDbase fontDbase, gxFont fontID, long *glyphCount, long *axisCount, long *variationCount, TfdbInfoFlags *flags)
- {
-
- OSErr status;
- long entryOffset; // Offset into handle.
- register unsigned char *p;
- register TFDBEntry *entry;
-
- status = GetCollectionItem((*(TFontDbaseHdl)fontDbase)->docFonts,
- (CollectionTag)fontID, // tag is the font id.
- nil,
- nil,
- &entryOffset);
- nrequire(status, failed_GetItem);
-
- p = (unsigned char*)((*(TFontDbaseHdl)fontDbase)->fontDbaseInfo) + entryOffset; // Point to entry.
-
- entry = (TFDBEntry*)(p);
-
- if (flags != nil)
- *flags = entry->flags;
-
- if (glyphCount != nil)
- *glyphCount = entry->fontInfo.glyphCount;
-
- if (axisCount != nil)
- *axisCount = entry->fontInfo.axisCount;
-
- if (variationCount != nil)
- *variationCount = entry->fontInfo.variationCount;
-
- failed_GetItem:
-
- return(status);
-
- }//FontDbaseGetFontInfo
-
-
- //<FF>
- /****************************************
-
- Function: FontDbaseGetGlyphBits
-
- Function returns a pointer to the bit
- array of glyph usage for a particular font.
- The pointer is only guarenteed to be valid
- if the font database is first locked in memory.
- However, the font database is not assumed
- to be locked before this call.
-
- fontDbase: The font database.
- fontID: The font to get bits of.
- snapshot: The index of the variation snapshot to retrieve bits for. (0 means union of all bits)
- glyphBits: <-- Pointer returned to bit array.
- variations: <-- Pointer to returned variation coordinate.
-
- ******************************************/
- OSErr FontDbaseGetGlyphBits(TFontDbase fontDbase, gxFont fontID, long snapshot, unsigned long* *glyphBits, gxFontVariation* *variations)
- {
- OSErr status;
- long entryOffset; // Offset into handle.
- register unsigned char *p;
- register TFDBEntry *entry;
- long glyphBitSize;
-
- status = GetCollectionItem((*(TFontDbaseHdl)fontDbase)->docFonts,
- (CollectionTag)fontID, // tag is the font id.
- nil,
- nil,
- &entryOffset);
- nrequire(status, failed_GetItem);
-
- p = (unsigned char*)((*(TFontDbaseHdl)fontDbase)->fontDbaseInfo) + entryOffset; // Point to entry.
-
- entry = (TFDBEntry*)p;
-
- p += sizeof(TFDBEntry) + 4 * ((entry->fontInfo.length + 3) / 4); // Skip name.
-
- /* p is now pointing at main bit array */
-
- if (snapshot > 0) {
-
- /* Skip to the right bit/variation pair */
-
- glyphBitSize = 4 * ((entry->fontInfo.glyphCount + 31) / 32);
-
- p += glyphBitSize; // Skip past main bit array.
-
- p += (snapshot - 1) * (glyphBitSize + entry->fontInfo.axisCount * sizeof(gxFontVariation));
-
- }//end if
-
- if (glyphBits != nil)
- *glyphBits = (unsigned long*)p;
-
- if (variations != nil)
- *variations = (gxFontVariation*)(p + glyphBitSize);
-
-
- //dprintf(notrace, "font: %d, nGlyphs: %d, bits: %X", fontID, entry->fontInfo.glyphCount, p);
-
- failed_GetItem:
-
- return(status);
-
- }//FontDbaseGetGlyphBits
-
- //<FF>
- /****************************************
-
- Function: FontDbaseGetIndexedFont
-
- Function gets a font reference from the
- database by index. Index is 1 based.
-
- fontDbase: A valid font database.
- index: The index of the font to get (1 based)
- fontID: (returned) The id of the font.
-
- *****************************************/
- OSErr FontDbaseGetIndexedFont(TFontDbase fontDbase, long index, gxFont *fontID)
- {
- OSErr status;
-
- status = GetIndexedCollectionItemInfo((*(TFontDbaseHdl)fontDbase)->docFonts, index,
- (CollectionTag*)fontID, nil, nil, nil);
- ncheck(status);
-
- return(status);
-
- }//FontDbaseGetIndexedFont
-
-
-
- /****************************************
-
- Function: FontDbaseCountFonts
-
- Function returns the number of fonts for the document
-
- *****************************************/
- OSErr FontDbaseCountFonts(TFontDbase fontDbase, long *numFonts)
- {
-
- *numFonts = (*(TFontDbaseHdl)fontDbase)->numFonts;
-
- return(noErr);
-
- }//FontDbaseCountFonts
-
-
-
- /******************************************
-
- Function: FontDbaseLock
-
- Locks down the font database in memory so
- pointers into it stay valid (such as glyphBits)
-
- ********************************************/
- OSErr FontDbaseLock(TFontDbase fontDbase)
- {
- register TFontDbasePtr pDbase = *(TFontDbaseHdl)fontDbase;
-
- if (pDbase->lockCount == 0)
- HLock((Handle)fontDbase);
-
-
- pDbase->lockCount += 1;
-
- return(MemError());
- }
-
-
-
- /*******************************************
-
- Function: FontDbaseUnlock
-
- Unlocks the font database in memory.
-
- ********************************************/
- OSErr FontDbaseUnlock(TFontDbase fontDbase)
- {
- register TFontDbasePtr pDbase = *(TFontDbaseHdl)fontDbase;
-
- pDbase->lockCount -= 1;
-
- if (pDbase->lockCount <= 0) {
-
- HUnlock((Handle)fontDbase);
-
- ncheck(pDbase->lockCount < 0);
-
-
- }//end if
-
- return(MemError());
- }
-
-
- //<FF>
- /***********************************************
-
- Routine: FDBIncludeFont
-
- Routine checks to see if a font should be included
- based upon the hExclusionList. The format of the exclusion
- list is a packed array of gxFlatFontName's, preceeded by
- a long count. If the list is nil, it means include all fonts.
-
- theFont: The font to see if should be included.
- hExclusionList: Handle to the packed array of gxFlatFontName's
- include: (returned) include the font or not.
-
- *************************************************/
- OSErr FDBIncludeFont(gxFont theFont, Handle hExclusionList, Boolean *include);
- OSErr FDBIncludeFont(gxFont theFont, Handle hExclusionList, Boolean *include)
- {
- OSErr status;
- long idx;
- long listSize; // number of entries in the list.
- unsigned char *p;
- gxFlatFontName *entry; // the current entry in the list.
- long nameSize;
- long biggestSize = 0;
- long nameIndex;
- Handle hName;
-
- if (hExclusionList == nil) {
-
- status = noErr;
- *include = true;
-
- } else {
-
- HLock(hExclusionList);
-
- p = (unsigned char*)*hExclusionList;
-
- *include = true;
-
- /* get the number of items in the list */
- listSize = *(long*)p;
- p += sizeof(long);
-
-
- /** Search the list **/
-
- idx = 0;
-
- status = PrNewHandle(&hName, 0); // allocate a zero size handle to start with for the name.
- nrequire(status, failed_Alloc);
-
- while (idx < listSize) {
-
- entry = (gxFlatFontName*)p;
-
- if (GXFindFontName(theFont, entry->name, entry->platform, entry->script, entry->language,
- nil, &nameIndex) ) {
-
- nameSize = GXGetFontName(theFont, nameIndex, nil, nil, nil, nil, nil);
-
- if (nameSize == entry->length) { // only bother comparing if sizes are the same
-
- /* make sure handle is big enough for name */
-
- if (nameSize > biggestSize) {
-
- status = PrSetHandleSize(hName, nameSize);
- nrequire(status, failed_resize);
- biggestSize = nameSize;
-
- }//end if
-
- /* actually get the name */
-
- HLock(hName);
- GXGetFontName(theFont, nameIndex, nil, nil, nil, nil, (unsigned char*)*hName);
- HUnlock(hName);
-
- /* Now compare the name to the one from the resource */
-
- if (!memcmp(*hName, p + sizeof(gxFlatFontName), entry->length)) {
- *include = false;
- break;
- }//end if
-
- }//end if
-
- }//end if
-
- p += sizeof(gxFlatFontName) + 4 * ((entry->length + 3) / 4);
- ++idx;
-
- }//end do
-
- failed_resize:
-
- DisposeHandle(hName);
- HUnlock(hExclusionList);
-
- }//end if
-
-
- failed_Alloc:
- return(status);
-
- }//FDBIncludeFont
-
- /***********************************************
-
- Routine: FontDbaseSpoolFonts
-
- Routine adds sfnt resources to the spool file for all document fonts.
- The resources are sparse fonts containing only the document required glyphs.
- Fonts get added to spool file as sfnt resources.
-
- fontDabse: The font database
- theFile: The spool file reference
- justAppFonts: true if you just want the application owned fonts, false for all fonts.
- hExclusionList: The list of fonts to exclude from the spool file.
- useMessages: use messages for adding resources, else use file handler directly.
-
- *************************************************/
- OSErr FontDbaseSpoolFonts(TFontDbase fontDbase, gxSpoolFile* theFile, Boolean justAppFonts, Handle hExclusionList)
- {
- OSErr status;
- long numFonts; // How many fonts?
- long i; // index for font
- gxFont fontRef; // Font to stream;
- unsigned long* glyphBits; // bit array for font glyph usage.
- gxFontAttribute theAttribute; // "What kind of font are you? I'm BatFont."
- Boolean includeFont; // Should we include this font.
- Boolean systemFont; // is it a system font.
- long prereqCount; // Number of prerequisite items for flattening.
-
- #if !GXTOPOSTSCRIPTLIBRARY
- /* Grabbing FONDs was only necessary for creating PDDs from non-GX apps */
- fontSfntMap** fontList; // list of font records for grabbing FONDs for embedding
- long fontListCount; // the number of records in fontList
- #endif
-
- TFile fileRef; // a temporary file for partial streaming
- Handle hStream; // a temporary handle for partial streaming
- Collection pictCollection; // used to detect if there are no quickdraw shapes
-
- status = FontDbaseLock(fontDbase);
- nrequire(status, failed_DbaseLock);
-
- status = FontDbaseCountFonts(fontDbase, &numFonts);
- nrequire(status, failed_CountFonts);
-
- #if !GXTOPOSTSCRIPTLIBRARY
- /* Grabbing FONDs was only necessary for creating PDDs from non-GX apps */
- status = PrNewHandle(&fontList, numFonts * sizeof(fontSfntMap));
- nrequire(status, failed_CountFonts);
- fontListCount = 0;
- #endif
-
- fileRef = nil; hStream = nil;
-
- for (i = 1; i <= numFonts; ++i) {
-
- status = FontDbaseGetIndexedFont(fontDbase, i, &fontRef);
- nrequire(status, failed_GetFont);
-
- /** Initialize the font info to exclude prerequisites **/
-
- status = FontDbaseExcludePrerequisite(fontDbase, fontRef, true);
- nrequire(status, failed_exclude1);
-
- // put the font in the file if either
- // a) we are placing all fonts in the file and it is not in the exclusion list (or list is nil)
- // b) the font is not a system font
-
- GXGetFont(fontRef, nil, &theAttribute);
-
- systemFont = (theAttribute & gxSystemFontAttribute) ? true : false;
- includeFont = !systemFont;
-
- if (!justAppFonts && systemFont) {
-
- status = FDBIncludeFont(fontRef, hExclusionList, &includeFont);
- nrequire(status, failed_IncludeFont);
-
- }//end if
-
- if (includeFont) {
-
- #if !GXTOPOSTSCRIPTLIBRARY
- /* Grabbing FONDs was only necessary for creating PDDs from non-GX apps */
- (*fontList)[fontListCount].fontID = fontRef;
- (*fontList)[fontListCount].newSfntRsrcID = 128 + i;
- ++fontListCount;
- #endif
-
- /** Turn off exclusion of prerequisites **/
-
- status = FontDbaseExcludePrerequisite(fontDbase, fontRef, false);
- nrequire(status, failed_exclude2);
-
- /** Get the bits **/
-
- status = FontDbaseGetGlyphBits(fontDbase, fontRef, 0, &glyphBits, nil);
- nrequire(status, failed_GetBits);
-
- /** We really need the file now if we don't have it **/
-
- if (fileRef == nil) {
- status = CreatePartialStreamTempFile(&fileRef, &hStream);
- nrequire(status, failed_CreateTempFile );
- }
-
- /** Make a handle **/
-
- status = FDBFontToHandle(fontRef, (long*)glyphBits, hStream);
- nrequire(status, failed_FontToHandle);
-
- // Important change: Using spool file C++ object instead of GX messages.
- status = theFile->SpoolResource(hStream, 'sfnt', 128 + i);
- nrequire(status, failed_SpoolRes);
-
- }//end if
-
- }//end for
-
- #if !GXTOPOSTSCRIPTLIBRARY
- /* PICT COLLECTION STUFF WAS ONLY NECESSARY FOR COMPATIBILITY PRINTING */
-
- /*
- * If this collection exists, but it has no entries, then we know
- * that we don't have any QD shapes, so we can skip the FONDs and NFNTs
- */
- status = SHGetPictCollection(theFile, &pictCollection);
- nrequire(status, failed_get_pict_collection);
- if ((pictCollection == nil || CountCollectionItems(pictCollection) > 0) && fontListCount > 0)
- {
- Handle FONDList;
- long FONDCount;
-
- HLock((Handle)fontList);
- status = FDBListOfReferencedFONDs(fontListCount, *fontList, &FONDCount, &FONDList);
- nrequire(status, failed_list_of_referenced_fonds);
- if (FONDCount > 0)
- { status = FDBAddFONDsToResourceFile(FONDCount, FONDList, theFile, useMessages);
- nrequire(status, failed_add_fonds_to_resource_file);
- }
- }
- #endif
-
- failed_get_pict_collection:
- failed_list_of_referenced_fonds:
- failed_add_fonds_to_resource_file:
-
- #if !GXTOPOSTSCRIPTLIBRARY
- DisposeHandle((Handle)fontList);
-
- if (status != noErr)
- goto failed_add_fonds;
-
- #endif
-
- /********* Now stream out any required prerequisites ***********/
-
-
- {
- unsigned char prereqItemData[256 + sizeof(scalerPrerequisiteItem)]; // Can't be any bigger 'cause name is pascal string
- scalerPrerequisiteItem *prereqItem = (scalerPrerequisiteItem*)prereqItemData;
- gxFont aFont;
- short theID;
-
- status = FontDbaseBuildPrerequisiteList(fontDbase, flattenedStreamType, nil, false, &prereqCount);
- nrequire(status, failed_buildPrereq);
-
- #if DEBUGLEVEL >= DEBUGFEEDBACK
- dprintf(trace, "# prerequisite items: %d", prereqCount);
- #endif
-
- for (i = 1; i <= prereqCount; ++i) {
-
- status = FontDbaseGetIndexedPrerequisite(fontDbase, i, nil, &aFont, prereqItem);
- nrequire(status, failed_getprereq);
-
- #if DEBUGLEVEL >= DEBUGFEEDBACK
- dprintf(trace, "Flattening prerequisite: %d for font: %d", prereqItem->enumeration, aFont);
- #endif
-
- if (fileRef == nil) {
- status = CreatePartialStreamTempFile(&fileRef, &hStream);
- nrequire(status, failed_CreateTempFile2 );
- }
-
- status = FDBPrereqToHandle(aFont, prereqItem, hStream);
- nrequire(status, failed_prereqToHandle);
-
- theID = 128 + 10 + numFonts + i; // ID will start at 128 + 10 more than number of fonts.
-
- // Change from sending gx message to using C++ class;
- status = theFile->SpoolResource(hStream, 'sfnt', theID);
- nrequire(status, failed_SpoolPrereq);
-
- /** Now name the resource with the prerequisite name so ATM can find it in the resource chain **/
- {
- Handle hFont = GetResource('sfnt', theID); // Get it again, only try to name it if we succeeded.
- if (hFont) {
-
- SetResInfo(hFont, theID, prereqItem->name);
-
- }//end if
- }
-
- }//end for
-
- }
-
-
- /***************** Now reset the prerequisite exclusion flags *******************/
-
- for (i = 1; i <= numFonts; ++i) {
-
- /** Clear the flag to exclude prerequisites **/
-
-
- status = FontDbaseGetIndexedFont(fontDbase, i, &fontRef);
- nrequire(status, failed_GetFont2);
-
- status = FontDbaseExcludePrerequisite(fontDbase, fontRef, true);
- nrequire(status, failed_exclude3);
-
- }//end for
-
- failed_exclude3:
- failed_GetFont2:
-
- failed_SpoolPrereq:
- failed_prereqToHandle:
- failed_CreateTempFile2:
- failed_getprereq:
- failed_buildPrereq:
-
- failed_add_fonds:
-
- failed_SpoolRes:
- failed_FontToHandle:
- failed_CreateTempFile:
- failed_GetBits:
- failed_SetFlags1:
- failed_exclude2:
- failed_IncludeFont:
- failed_exclude1:
- failed_GetFont:
- {
- if( fileRef )
- DisposePartialStreamTempFile( fileRef, hStream );
- }
-
- failed_CountFonts:
- {
- OSErr saveStatus = FontDbaseUnlock(fontDbase);
- if (status == noErr)
- status = saveStatus;
-
- ncheck(status);
- }
-
- failed_DbaseLock:
-
- return(status);
-
- }//FontDbaseSpoolFonts
-
-
-
-
-
- //<FF>
- /*************************************
-
- Function: FontDbaseUnion
-
- Function makes a copy of a font database object.
-
-
- source: Font database object to copy.
- target: Union entries from source font database into this font database.
-
- ***************************************/
- OSErr FontDbaseUnion(TFontDbase source, TFontDbase target)
- {
- OSErr status, saveStatus;
- long index;
- TFontDbaseHdl hSource;
- Collection sourceOffsets;
- long offset;
- gxFlatFontListItem *sourceItem;
- unsigned char *p;
- Boolean useMac8bitEncoding;
-
- status = FontDbaseLock(source);
- nrequire(status, failed_Lock);
-
- hSource = (TFontDbaseHdl)source;
-
- sourceOffsets = (*hSource)->docFonts;
-
- for (index = 1; index <= (*hSource)->numFonts; ++index) {
-
- status = GetIndexedCollectionItem(sourceOffsets, index, nil, &offset);
- nrequire(status, failed_GetItem);
-
- p = (unsigned char*)((*hSource)->fontDbaseInfo) + offset; // Point to entry.
-
- if ( ((TFDBEntry*)p)->flags & fdbUseMac8Bit)
- useMac8bitEncoding = true;
- else
- useMac8bitEncoding = false;
-
- sourceItem = &( ((TFDBEntry*)p)->fontInfo);
-
- status = FontDbaseAddItem(target, sourceItem, useMac8bitEncoding);
- nrequire(status, failed_AddItem);
-
- }//end for
-
- failed_AddItem:
- failed_GetItem:
- failed_Lock:
- saveStatus = FontDbaseUnlock(source);
- if (status == noErr)
- status = saveStatus;
-
- return(status);
-
- }//FontDbaseUnion
-
-